#pragma once

#include <windef.h>
#include <boost/function.hpp>

#include "exports.hpp"




#pragma warning (push)
#pragma warning (disable: 4251)

/**
 * This class simplifies the installation of a mouse hook.
 * It can be used to intercept mouse messages.
 * Aimed at simplicity, the class accepts a boost functor that
 * can be bound to anything, even a member function.
 *
 * However, this class may only be used in the main thread of the
 * application. It may, under no circumstances be used in \b any
 * other thread.
 *
 * @warning   do not use this class in multiple threads, it is not thread safe.
 *            The class will do a check in debug builds only and crash on purpose
 *            if the calling thread differs from the main thread.
 */
class HOOKS_API MouseHook
{
public:

	typedef boost::function<void (WPARAM,LPARAM)> MouseProc;

private:

	MouseProc m_mouseProc;
	HWND      m_window;

public:

	/**
	 * Registers a MouseHook.
	 *
	 * @param mouseProc   functor that is called when a mouse message is being processed
	 * @param window      handle to the window who's mouse messages shall be intercepted
	 */
	MouseHook(const MouseProc& mouseProc, HWND window = NULL);

	/**
	 * Unregisters the MouseHook.
	 */
	~MouseHook();



	/**
	 * Call the mouse procedure.
	 */
	void mouseProc(WPARAM wParam, LPARAM lParam) const;

	/**
	 * Get the window who's messages shall be intercepted
	 */
	HWND window() const;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
